require "rubygems"
require "capistrano"

require "pathname"
additional_path = Pathname.new(__FILE__).realpath.dirname.join("..", "..", "..")
$: << additional_path

require "wondercap/lib/capistrano/fileutils"
require "wondercap/lib/capistrano/syscmd"
require "wondercap/lib/capistrano/variables"

module Capistrano
  class Configuration
    include Wondercap::CapistranoMixins::FileUtils
    include Wondercap::CapistranoMixins::Syscmd
    include Wondercap::CapistranoMixins::Variables
  end
end

require "wondercap/lib/utils/string_mixin"
class String
  include Wondercap::StringMixin
end

require "wondercap/lib/utils/hash_mixin"
class Hash
  include Wondercap::HashMixin
end

module Wondercap
  
  class CLI
    def execute(args, env)
      trap "INT" do
        puts caller.join("\n\t")
        exit 1
      end
      begin
        parse_args(args, env)

        outer_configuration = Capistrano::Configuration.new
        outer_configuration.set :names, arg || ""
        vars.each do |k,v|
          outer_configuration.set k, v
        end        
        
        outer_configuration.load_paths << File.join(File.dirname(__FILE__), "..", "..", "..")
        outer_configuration.load("wondercap/lib/deployment/recipes/deployment")
        outer_configuration.trigger :load
        
        safe_for_inner_vars = vars.reject { |k,v| [:area, :area_name, :snapshot, :sid, :filters, :tags, :names].include? k }
        outer_configuration.configuration(:base) do
          safe_for_inner_vars.each do |k,v|
            set(k, v) unless exists? k
          end
        end
        
        outer_configuration.set(:top_task) {
          outer_configuration.find_task(command) || outer_configuration.find_task("wondercap:#{command.to_s}") || outer_configuration.find_task("wondercap:execute_task_on_names")
        }
        outer_configuration.trigger :start
        begin
          if outer_configuration.top_task.fully_qualified_name != "wondercap:execute_task_on_names"
            outer_configuration.find_and_execute_task outer_configuration.top_task.fully_qualified_name
          else
            outer_configuration.set :task, command
            outer_configuration.find_and_execute_task "wondercap:execute_task_on_names"
          end
        ensure
          outer_configuration.trigger :finish
        end
      rescue => e
        puts "error #{e}: #{e.message}"
        puts e.backtrace.join("\n\t")
        raise e
      end
    end
    
    private
    attr_reader :command, :arg, :vars
    def parse_args(argv, env)
      @command = argv[0]
      @arg = argv.delete_at(1) if argv.length >= 2 && argv[1] !~ /=/
      @vars = {}
      (argv[1..-1] || []).each do |ar|
        if ar =~ /^(\w+)=(.+)$/
          @vars[$1.to_sym] = $2
        else
          @vars[ar.to_sym] = true
        end
      end
    end
    
  end
  
end